// Three pieces need to be configured to use Passport for authentication:
//
// 1. Authentication strategies
// 2. Application middleware
// 3. Sessions (optional)

var LocalStrategy = require('passport-local').Strategy;
var MAX_LOGIN_ATTEMPTS = 5;
var LOCKED_TIME = 1000*60*60*2;  // two hours

    
module.exports = function(passport) {
   // @override
   passport.serializeUser(function(user, done) {
      done(null,  {uid: user._id, test: 'test test'} );   // serialize obj into session cookie
   });

   // @override
   passport.deserializeUser(function(cookie_obj, done) {
      var uid = cookie_obj.uid;      
      Domain.User.findById(uid).populate('club').populate('joinedclubs').exec(function(err, user){ // populate 'club' because of this: user.'club'
         done(err, user);
      });
   });

   // my-local-signup
   passport.use('my-local-signup', new LocalStrategy({
      // by default, local strategy uses username and password, we will override with email
      usernameField     : 'email',
      passwordField     : 'password',
      passReqToCallback : true // allows us to pass back the entire request to the callback
   },
   function(req, email, password, done) {
      var regex = new RegExp(["^", email, "$"].join(""), "i");
      Domain.User.findOne({ 'local.email' :  regex }, function(err, user) {
         if (err) return done(err);
         if (user)return done(null, false, req.flash('signupMessage', 'That email is already taken.'));

         // if there is no user with that email
         // create the user
         var newUser            = new Domain.User();
         newUser.local.email    = email;
         newUser.local.password = newUser.generateHash(password);      // use the generateHash function in our user model
         newUser.firstname      = CapFirstLetter(req.body.firstname);  // customized additional field
         newUser.lastname       = CapFirstLetter(req.body.lastname);   // customized additional field
         newUser.login_attempts = 1;
         newUser.role           = 'member';

         newUser.save(function(err) {
            if (err) throw err;
            return done(null, newUser);
         });
      });
   }));

   // my-local-login
   passport.use('my-local-login', new LocalStrategy({
      usernameField     : 'email',
      passwordField     : 'password',
      passReqToCallback : true 
   },
   function(req, email, password, done) { // callback with email and password from our form
      var regex = new RegExp(["^", email, "$"].join(""), "i");
      Domain.User.findOne({ 'local.email' :  regex }, function(err, user) {
         if (err)
            return done(err);

         // User Not Found
         if (!user)
            return done(null, false, req.flash('loginMessage', 'The email or password you entered is incorrect.'));

         // User Found With Locked Account
         if(user.locked_until > Date.now()){
            return done(null, false, req.flash('loginMessage', 'This account has been locked until ' + user.locked_until));

         // User Found With Incorrect Password
         }else if (!user.validPassword(password)){  

            // Login Attempts < MAX_LOGIN_ATTEMPTS
            if(user.login_attempts < MAX_LOGIN_ATTEMPTS){
               Domain.User.update({_id: user._id}, {$inc: {login_attempts: 1}}, function(err, num){
                  if(err) throw err;
                  return done(null, false, req.flash('loginMessage', 'This account will be locked after ' + (MAX_LOGIN_ATTEMPTS - user.login_attempts) + ' more failed logins.' ));
               });

            // Login Attempts >= MAX_LOGIN_ATTEMPTS
            }else{
               Domain.User.update({_id: user._id}, {login_attempts: 1, locked_until: Date.now() + LOCKED_TIME}, function(err, num){
                  if(err) throw err;
                  return done(null, false, req.flash('loginMessage', 'This account has been locked.'));
               });
            }

         // User Found with Correct Password
         }else{
            Domain.User.update({_id: user._id}, {login_attempts : 1}, function(err, num){
               if(err) throw err;
               return done(null, user);   // to access user in router: req.user, then it will be passed to 'user' in view
            });
         }
      });
   }));

};

function CapFirstLetter(string){
   return string.charAt(0).toUpperCase() + string.slice(1);
}
